#ifndef HTTPCONN_H
#define HTTPCONN_H

#include<sys/epoll.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>//包含上面两？
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
// #include<sys/epoll.h>
#include "locker.h"
#include "threadpool.h"
#include<signal.h>
// #include "http_conn.h"
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/mman.h>
#include<stdarg.h>
#include<sys/uio.h>

class http_conn{
private:
    int m_sockfd;//该http连接的socket
    sockaddr_in m_address;//通信的socket地址
    static const int READ_BUFFER_SIZE=2048;//读缓冲区的大小
    static const int WRITE_BUFFER_SIZE=1024;//写缓冲区的大小
    char m_read_buf[READ_BUFFER_SIZE];//读缓冲区
    int m_read_index=0;//标识读缓冲区中读入的客户端数据的最后一个字节的下一位

    int m_checked_index=0;//当前在分析的字符在读缓冲区的位置
    int m_start_line=0;//当前正在解析的行的起始位置

    

    //http请求方法 我们只支持get
    enum METHOD{GET=0,POST,HEAD,PUT,DELETE,TRACE,OPTIONS,CONNECT};
    /*
    解析客户端请求时，主状态机的状态
    CHECK_STATE_REQUESTLINE 当前正在分析请求行
    CHECK_STATE_HEADER 当前正在分析请求头部
    CHECK_STATE_CONTENT 当前正在分析请求体
    */
    enum CHECK_STATE{CHECK_STATE_REQUESTLINE=0,CHECK_STATE_HEADER,CHECK_STATE_CONTENT};

    //从状态机的三种可能状态，即行的读取状态，分别表示
    //1.读取到一个完整的行 2.行出错 3.行数据尚且不完整
    enum LINE_STATUS{LINE_OK=0,LINE_BAD,LINE_OPEN};

    /*
        服务器处理http请求的可能结果，报文解析的结果：
        NO_REQUEST         请求不完整，需要继续读取客户数据
        GET_REQUEST        表示获得了一个完整的客户请求
        BAD_REQUEST        表示客户端请求语法错误
        NO_RESOURCE        表示服务器没有资源
        FORBIDDEN_REQUEST  表示客户对资源没有足够的访问权限
        FILE_REQUEST       文件请求，获取文件成功
        INTERNAL_ERROR     表示服务器内部错误
        CLOSED_CONNECTION  表示客户端已经关闭连接了
    */
    enum HTTP_CODE{NO_REQUEST,GET_REQUEST,BAD_REQUEST,NO_RESOURCE,FORBIDDEN_REQUEST,FILE_REQUEST,INTERNAL_ERROR,CLOSED_CONNECTION};

    CHECK_STATE m_check_state=CHECK_STATE_REQUESTLINE;//主状态机当前所处的状态

    void init();

    char* m_url=nullptr;//请求目标文件的文件名
    char* m_version=nullptr;//协议版本，只支持HTTP1.1
    METHOD m_method=GET;//请求方法

    char* m_host=nullptr;//主机名
    bool m_linger=false;//HTTP请求是否要保持连接

    int m_content_length=0;


    char* my_real_file=nullptr;
    char* doc_root="/home/lauirf/test/server/webserver/resourece";

    stat* m_file_stat=nullptr;
    char* my_file_address=nullptr;
public:
    http_conn(){

    }
    ~http_conn(){

    }
    //由线程池中的工作线程调用，处理http请求的入口函数
    void process();
    static int m_epollfd;//所有socket上的事件都被注册到同一个epollf对象中
    static int m_user_count;//统计用户的数量

    //初始化新接受的连接
    void init(int connfd,const struct sockaddr_in &client_address);

    //关闭连接
    void close_conn();

    //非阻塞的读
    bool read();

    //非阻塞的写
    bool write();

    //解析HTTP请求
    HTTP_CODE process_read();

    //解析请求首行
    HTTP_CODE parse_request_line(char* text);

    //解析请求头
    HTTP_CODE parse_headers(char* text);

    //解析请求体
    HTTP_CODE parse_content(char* text);

    //解析一行
    LINE_STATUS parse_line();

    char* get_line(){
        return m_read_buf+m_start_line;
    }

    HTTP_CODE do_request();

};


#endif